﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace linkouqs.Gamekit
{

    public class CharacterSlot : MonoBehaviour
    {

        class SlotData
        {
            public Transform Slot;
            public Transform Target;
            public Transform OldParent;

            public bool IsAttached { get { return Target != null; } }

            public void Attach(Transform trans)
            {
                if (IsAttached)
                {
                    throw new System.Exception("An object which named '"
                     + Target.name
                     + "' is attached to slot["
                     + Slot.name + "], please do Detach(slotName) at first.");
                }

                Target = trans;
                OldParent = Target.parent;
                Target.SetParent(Slot);
            }

            public Transform Detach()
            {
                if (!IsAttached)
                {
                    return null;
                }

                var trans = Target;
                trans.SetParent(OldParent);
                Target = null;
                OldParent = null;
                return trans;
            }

            public void Release()
            {
                Slot = null;
                Target = null;
                OldParent = null;
            }
        }

        Dictionary<string, SlotData> m_SlotDict = new Dictionary<string, SlotData>();

        void Awake()
        {
            InitSlots();
        }

        void InitSlots()
        {
            for (int i = 0, len = transform.childCount; i < len; i++)
            {
                var slot = transform.GetChild(i);
                if (slot.name.ToLower().EndsWith("slot", System.StringComparison.Ordinal))
                {
                    m_SlotDict.Add(slot.name, new SlotData()
                    {
                        Slot = slot
                    });
                }
            }

        }

        void ReleaseSlots()
        {
            foreach (var kvp in m_SlotDict)
            {
                kvp.Value.Release();
            }
            m_SlotDict.Clear();
        }

        public bool HasSlot(string slotName)
        {
            return m_SlotDict.ContainsKey(slotName);
        }

        public bool IsAttached(string slotName)
        {
            return m_SlotDict[slotName].IsAttached;
        }

        public Transform Attach(string slotName, Transform trans)
        {
            var slot = m_SlotDict[slotName];
            slot.Attach(trans);
            return slot.Slot;
        }

        public Transform Detach(string slotName)
        {
            return m_SlotDict[slotName].Detach();
        }

        void OnDestroy()
        {
            ReleaseSlots();
        }

    }

}
